package com.yanqu.road.server.manger.activity.jiuzhou;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.jiuzhou.JiuZhouActivityChampionData;
import com.yanqu.road.entity.activity.jiuzhou.JiuZhouChampionUserData;
import com.yanqu.road.entity.activity.jiuzhou.config.JiuZhouConfig;
import com.yanqu.road.entity.activity.jiuzhou.config.JiuZhouRoundConfig;
import com.yanqu.road.entity.enums.activity.jiuzhou.eJiuZhouRoundType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.logic.bussiness.activity.JiuZhouBussiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.PatronsPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.jiuzhou.CrossJiuZhouProto;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.jiuzhou.JiuZhouProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.jiuzhou.JiuZhouModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 九州棋局
 */
public class JiuZhouMgr extends TempMgr {

    private static JiuZhouConfig config = null;

    /**
     * 九州门客缓存数据
     */
    private static Map<Long, List<UserPatrons>> patronsCacheMap = new ConcurrentHashMap<>();

    /**
     * 最近一次上报时间
     */
    private static long lastUploadTime;

    /**
     * 历届冠军map
     */
    private static Map<Integer, JiuZhouActivityChampionData> historyChampionMap = new ConcurrentHashMap<>();

    @Override
    public boolean save() {
        if (historyChampionMap != null){
            for (JiuZhouActivityChampionData championData:historyChampionMap.values()){
                if (championData.isInsertOption()){
                    JiuZhouBussiness.addJiuZhouActivityChampionData(championData);
                }else if (championData.isUpdateOption()){
                    JiuZhouBussiness.updateJiuZhouActivityChampionData(championData);
                }
            }
        }
        return true;
    }

    /**
     * 门客同步定时器
     */
    public static void patronsUploadAbilityTask() {
        if (config == null || !ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        long nowTime = System.currentTimeMillis();
        // 每5秒同步一次
        if (nowTime - lastUploadTime < 5 * DateHelper.SECOND_MILLIONS) {
            return;
        }
        uploadPatronsAbility();
    }

    /**
     * 门客变更加到缓存里
     *
     * @param forceUpload 强制上报
     */
    public static void addPatronsUploadAbility(long userId, List<UserPatrons> patronsList, boolean forceUpload) {
        if (config == null || !ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        synchronized (patronsCacheMap) {
            patronsCacheMap.put(userId, patronsList);
        }
        // 超过10个就上报
        if (forceUpload || patronsCacheMap.size() >= 10) {
            uploadPatronsAbility();
        }
    }

    /**
     * 上报
     */
    public static void uploadPatronsAbility() {
        if (config == null || !ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        if (patronsCacheMap.isEmpty()) {
            return;
        }
        Map<Long, List<UserPatrons>> tempMap = new ConcurrentHashMap<>();
        synchronized (patronsCacheMap) {
            tempMap = new ConcurrentHashMap<>(patronsCacheMap);
            patronsCacheMap.clear();
        }
        CrossJiuZhouProto.CrossJiuZhouUploadPatronsAbilityMsg.Builder builder = CrossJiuZhouProto.CrossJiuZhouUploadPatronsAbilityMsg.newBuilder();
        builder.setActivityId(config.getActivityInfo().getActivityId());
        for (Map.Entry<Long, List<UserPatrons>> entry : tempMap.entrySet()) {
            CrossJiuZhouProto.CrossJiuZhouPatronsUserTemp.Builder temp = CrossJiuZhouProto.CrossJiuZhouPatronsUserTemp.newBuilder();
            temp.setUserId(entry.getKey());
            for (UserPatrons userPatrons : entry.getValue()) {
                temp.addPatronsData(PatronsPb.parsePatronsSimpleTempMsg(userPatrons));
            }
            builder.addUser(temp);
        }
        GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_JIU_ZHOU_UPLOAD_PATRONS_ABILITY, builder));

        lastUploadTime = System.currentTimeMillis();
    }



    private static AtomicBoolean isUploading = new AtomicBoolean(false);

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        if (historyChampionMap == null || historyChampionMap.isEmpty()){
            historyChampionMap = JiuZhouBussiness.getJiuZhouActivityChampionMapData();
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    /**
     * 重新加载活动
     */
    public static void reloadActivityData() {
        getLogger().info("reload jiuzhou start");
        List<ActivityInfo> list = NormalActivityMgr.getOpenActivityInfoList(eActivityType.JiuZhou.getValue());
        if (list.isEmpty()) {
            config = null;
            getLogger().info("reload jiuzhou end, no activity in show time.");
            return;
        }
        ActivityInfo activityInfo = list.get(0);
        // 加载活动
        JiuZhouConfig tempConfig = new JiuZhouConfig();
        tempConfig.setActivityInfo(activityInfo);
        // 加载一下通用活动配置
        tempConfig.initConfig(NormalActivityMgr.getActivityConfigMap(activityInfo.getActivityId()));

        Map<Integer, JiuZhouRoundConfig> jiuZhouRoundConfigMap = JiuZhouBussiness.getJiuZhouRoundConfigMap(activityInfo.getActivityId());
        for (JiuZhouRoundConfig roundConfig : jiuZhouRoundConfigMap.values()) {
            String time = roundConfig.getTime();
            List<Integer> integerList = StringUtils.stringToIntegerList(time, "\\|");
            roundConfig.setTimeList(integerList);
        }

        tempConfig.setRoundConfigMap(jiuZhouRoundConfigMap);
        tempConfig.setSkillConfigMap(JiuZhouBussiness.getJiuZhouSkillConfigMap(activityInfo.getActivityId()));

        config = tempConfig;
        getLogger().info("reload jiuzhou end, activityId {}.", config.getActivityInfo().getActivityId());

        // 在线用户推数据
        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(JiuZhouModule.class).syncData();
        }
    }

    public static JiuZhouConfig getConfig() {
        return config;
    }

    public static Map<Integer,Map<Integer,Long>> getInitGuessMap(){
        if (config == null){
            return null;
        }
        Map<Integer, JiuZhouRoundConfig> roundConfigMap = config.getRoundConfigMap();
        if (roundConfigMap == null || roundConfigMap.isEmpty()){
            return null;
        }

        Map<Integer,Map<Integer,Long>> guessMap = new ConcurrentHashMap<>();
        for (JiuZhouRoundConfig roundConfig : roundConfigMap.values()) {
            if (roundConfig.getType() != eJiuZhouRoundType.knockout.getValue()){
                continue;
            }
            guessMap.put(roundConfig.getId(),new ConcurrentHashMap<>());
        }
        return guessMap;
    }

    public static Map<Integer,Integer> getInitGuessRewardMap(){
        if (config == null){
            return null;
        }
        Map<Integer, JiuZhouRoundConfig> roundConfigMap = config.getRoundConfigMap();
        if (roundConfigMap == null || roundConfigMap.isEmpty()){
            return null;
        }

        Map<Integer,Integer> guessRewardMap = new ConcurrentHashMap<>();
        for (JiuZhouRoundConfig roundConfig : roundConfigMap.values()) {
            if (roundConfig.getType() != eJiuZhouRoundType.knockout.getValue()){
                continue;
            }
            guessRewardMap.put(roundConfig.getId(),0);
        }
        return guessRewardMap;
    }

    public static void uploadEarnSpeed(int activityId){
        getLogger().info("九州棋局活动收到跨服请求,上传赚速数据,活动id:{}",activityId);
        if (config == null){
            getLogger().error("九州棋局活动没有找到活动,暂不上传赚速数据! 活动id{}",activityId);
            return;
        }
        if (config.getActivityId() != activityId){
            getLogger().error("九州棋局活动id不匹配,暂不上传赚速数据! 活动id{}",activityId);
            return;
        }
        //如果在上传的时候收到了请求 那就skip
        if (isUploading.get()){
            return;
        }
        int levelLimit = config.getLevelLimit();
        int patronLimit = config.getSighLimit();
        isUploading.set(true);
        Map<Long,BigInteger> canSignAbilityMap = new ConcurrentHashMap<>();
        try {
            canSignAbilityMap = JiuZhouBussiness.getCanSignUserAbility(levelLimit, patronLimit);
        }catch (Exception e){
            getLogger().error("九州棋局活动上传赚速数据读取数据库异常! 活动id{}",activityId);
            isUploading.set(false);
            e.printStackTrace();
            return;
        }
        if (canSignAbilityMap == null){
            getLogger().error("九州棋局活动没有找到可上传的用户,暂不上传赚速数据! 活动id{}",activityId);
            isUploading.set(false);
            return;
        }
        //没满足的也给他传上去了
        if (canSignAbilityMap.isEmpty()){
            getLogger().error("九州棋局活动没有找到可上传的用户! 活动id{}",activityId);
//            getLogger().error("九州棋局活动没有找到可上传的用户,暂不上传赚速数据! 活动id{}",activityId);
//            isUploading.set(false);
//            return;
        }
        CrossJiuZhouProto.UploadUserAbilityMsg.Builder builder = CrossJiuZhouProto.UploadUserAbilityMsg.newBuilder();
        builder.setActivityId(activityId);
        for (Map.Entry<Long,BigInteger> entry : canSignAbilityMap.entrySet()) {
            long userId = entry.getKey();
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            if (userInfo == null){
                continue;
            }
            //拿出玩家的最后登录时间
            long lastLoginTime = userInfo.getLastLoginTime();
            //拿出当前秒
            long now = System.currentTimeMillis() / DateHelper.SECOND_MILLIONS;
            //拿出离线天数
            int offlineDays = (int) ((now- lastLoginTime) / DateHelper.DAY_SECONDS);
            //七天外的不加
            if (offlineDays > 7) {
                continue;
            }
            builder.addAbility(entry.getValue().toString());
        }

        if (ServerListMgr.getChannelId(GameServer.getInstance().getServerId()) == 666){
//            getLogger().error("九州棋局活动上传赚速数据 详细赚速为! 活动id{}",activityId);
//            canSignAbility.forEach(s -> getLogger().error("赚速:"+s));
        }

        YanQuMessage yanQuMessage = YanQuMessageUtils.buildMessage(CrossProtocol.C_JIU_ZHOU_GAME_SEND_ABILITY_TO_CROSS, builder);
        GamePlayerMgr.sendPacket(0,yanQuMessage);
        //上传完成
        isUploading.set(false);
        getLogger().info("九州棋局活动上传赚速数据完成! 活动id{},上传玩家数{}",activityId,canSignAbilityMap.size());
    }

    public static Property getGuessRewardByRightNum(int roundId,int rightNum){
        if (config == null){
            getLogger().error("九州棋局领取奖励活动不存在");
            return null;
        }
        if (config.getRoundConfigMap() == null || !config.getRoundConfigMap().containsKey(roundId)){
            getLogger().error("九州棋局活动猜中奖励参数配置错误! roundId{}",roundId);
            return null;
        }
        JiuZhouRoundConfig roundConfig = config.getRoundConfigMap().get(roundId);
        String guessParam = roundConfig.getGuessParam();
        List<Integer> guessParamList = StringUtils.stringToIntegerList(guessParam, "\\|");
        if (guessParamList.size() < 4){
            getLogger().error("九州棋局活动猜中奖励参数配置错误! roundId{}",roundId);
            return null;
        }
        if (rightNum < 0 || rightNum > 3){
            getLogger().error("九州棋局活动猜中奖励参数错误! roundId{},rightNum{}",roundId,rightNum);
            return null;
        }
        int rewardNum = guessParamList.get(rightNum);
        int itemId = config.getMoneyItemId1();
        Property property = new Property(itemId,rewardNum);
        return property;
    }

    public static void jumpTest(String param) {
        if (param.equals("0")) {
            config.getActivityInfo().setBeginTime(config.getActivityInfo().getBeginShowTime());
        } else {
            List<Integer> integerList = StringUtils.stringToIntegerList(param, "-");
            int roundId = integerList.get(0);
            int roundState = integerList.get(1);
            long now = System.currentTimeMillis();
            JiuZhouRoundConfig roundConfig = config.getRoundConfigMap().get(roundId);
            if (roundConfig == null) {
                return;
            }
            List<Integer> timeList = roundConfig.getTimeList();
            if (roundState >= timeList.size()) {
                return;
            }
            long startTime = now - (timeList.get(roundState) * DateHelper.MINUTE_MILLIONS);
            config.getActivityInfo().setBeginTime(startTime / 1000);
        }
    }

    /**
     * 活动开始时间+分钟转化为时间戳
     */
    public static long getTimeStampAfterBegin(int minute){
        if (config == null){
            return 0;
        }
        return config.getActivityInfo().getBeginTime() * DateHelper.SECOND_MILLIONS + (long) minute * DateHelper.MINUTE_MILLIONS;
    }

    /**
     * 检测九州当前活动的冠军有没有
     */
    public static void checkJiuZhouActivityWinner(){
        //如果没有活动配置或者活动不在开启时间内
        if (config == null || !ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        //看看是否已经有本次活动冠军了
        if (historyChampionMap != null && !historyChampionMap.isEmpty()){
            if (historyChampionMap.containsKey(config.getActivityId())){
                JiuZhouActivityChampionData jiuZhouActivityChampionData = historyChampionMap.get(config.getActivityId());
                //只有三个赛区都有冠军了才不用再去跨服找了
                if (jiuZhouActivityChampionData != null && jiuZhouActivityChampionData.getChampionMap().size() >= 3){
                    return;
                }
            }
        }
        //如果没有冠军,那就看看是不是打完了
        Map<Integer, JiuZhouRoundConfig> roundConfigMap = config.getRoundConfigMap();
        if (roundConfigMap == null || roundConfigMap.isEmpty()){
            return;
        }
        for (JiuZhouRoundConfig roundConfig:roundConfigMap.values()){
            //找出最后一轮的配置
            if (roundConfig.getId() == config.getMaxRound()) {
                continue;
            }
            List<Integer> timeList = roundConfig.getTimeList();
            long timeStampAfterBegin = getTimeStampAfterBegin(timeList.get(3));
            //判断当前时间是不是已经最后一轮结束了
            if (System.currentTimeMillis() < timeStampAfterBegin){
                return;
            }
            //如果结束了,那就去跨服找出最后一轮的冠军
            CrossJiuZhouProto.CrossJiuZhouGetChampionDataReqMsg.Builder builder = CrossJiuZhouProto.CrossJiuZhouGetChampionDataReqMsg.newBuilder();
            builder.setActivityId(config.getActivityInfo().getActivityId());
            GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(CrossProtocol.C_JIU_ZHOU_GET_CHAMPION_DATA, builder));
            return;
        }
    }

    /**
     * 收到跨服返回的冠军数据
     */
    public static void receiveChampionData(CrossJiuZhouProto.CrossJiuZhouGetChampionDataResultMsg respMsg){
        if (respMsg == null){
            return;
        }
        if (respMsg.getChampionDataList().isEmpty()){
            return;
        }
        int activityId = respMsg.getActivityId();
        //如果有冠军数据,那就把冠军数据存起来
        if (historyChampionMap == null){
            historyChampionMap = new ConcurrentHashMap<>();
        }
        //如果回来的包数据是空的 直接弹出去
        if (respMsg.getChampionDataList().isEmpty()){
            return;
        }
        ActivityInfo openActivityInfo = ActivityMgr.getOpenActivityInfo(respMsg.getActivityId());
        if (openActivityInfo == null){
            getLogger().error("活动id为{}的九州棋局活动收到获取回包时活动已经不存在",activityId);
            return;
        }


        Map<Integer, JiuZhouChampionUserData> tmpChampionMap = new ConcurrentHashMap<>();
        for (JiuZhouProto.JiuZhouChampionDataMsg championData:respMsg.getChampionDataList()){

            UserBaseInfo userBaseInfo = PlayerBasePb.parseToUserBaseInfo(championData.getUserBaseInfo());
            JiuZhouChampionUserData championUserData = new JiuZhouChampionUserData(championData.getUserId(),userBaseInfo,championData.getTitleId());
            tmpChampionMap.put(championData.getZoneType(),championUserData);
        }

        JiuZhouActivityChampionData jiuZhouActivityChampionData = historyChampionMap.get(activityId);
        if (jiuZhouActivityChampionData != null){
            getLogger().debug("九州活动{}收到冠军数据更新",activityId);
            jiuZhouActivityChampionData.setChampionMap(tmpChampionMap);
            jiuZhouActivityChampionData.setServerIdList(new ArrayList<>(openActivityInfo.getServerIdList()));
        }else {
            getLogger().debug("九州活动{}收到全量冠军数据",activityId);
            JiuZhouActivityChampionData tmpChampionData = new JiuZhouActivityChampionData(activityId,tmpChampionMap,new ArrayList<>(openActivityInfo.getServerIdList()),respMsg.getTimestamp());
            tmpChampionData.setInsertOption();
            historyChampionMap.put(activityId,tmpChampionData);
        }


    }

    /**
     * 获取当前活动的某个赛区的冠军
     */
    public static JiuZhouChampionUserData getChampionUserData(int activityId,int zoneType){
        if (historyChampionMap == null){
            return null;
        }
        if (!historyChampionMap.containsKey(activityId)){
            return null;
        }
        JiuZhouActivityChampionData championData = historyChampionMap.get(activityId);
        if (championData == null){
            return null;
        }
        Map<Integer, JiuZhouChampionUserData> championUserDataMap = championData.getChampionMap();
        if (championUserDataMap == null){
            return null;
        }
        if (!championUserDataMap.containsKey(zoneType)){
            return null;
        }
        return championUserDataMap.get(zoneType);
    }


    /**
     * 获取历史的所有冠军
     */
    public static List<JiuZhouProto.JiuZhouActivityChampionDataMsg> getHistoryChampionMsg(int activityId){
        List<JiuZhouProto.JiuZhouActivityChampionDataMsg> respMsgList = new ArrayList<>();

        if (config == null){
            return null;
        }
        if (config.getActivityId() != activityId){
            return null;
        }

        ActivityInfo activityInfo = NormalActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null){
            return null;
        }
        for (Map.Entry<Integer,JiuZhouActivityChampionData> entry:historyChampionMap.entrySet()){

            JiuZhouProto.JiuZhouActivityChampionDataMsg.Builder builder = JiuZhouProto.JiuZhouActivityChampionDataMsg.newBuilder();
            JiuZhouActivityChampionData value = entry.getValue();
            builder.setActivityId(entry.getKey());
            builder.setTime(value.getTime());
            for (Map.Entry<Integer, JiuZhouChampionUserData> userDataEntry:value.getChampionMap().entrySet()){
                JiuZhouProto.JiuZhouChampionDataMsg.Builder dataBuilder = JiuZhouProto.JiuZhouChampionDataMsg.newBuilder();

                JiuZhouChampionUserData userData = userDataEntry.getValue();

                dataBuilder.setZoneType(userDataEntry.getKey());
                dataBuilder.setUserId(userData.getUserId());
                dataBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getUserBaseInfo()));
                dataBuilder.setTitleId(userData.getTitleItemId());

                builder.addChampionData(dataBuilder);
            }
            builder.addAllServerId(value.getServerIdList());
            respMsgList.add(builder.build());

        }
        //如果当前活动没有历史冠军数据,那就返回一个空的
        if (!historyChampionMap.containsKey(activityId)){
            JiuZhouProto.JiuZhouActivityChampionDataMsg.Builder dataBuilder = JiuZhouProto.JiuZhouActivityChampionDataMsg.newBuilder();
            dataBuilder.setActivityId(activityId);
            dataBuilder.setTime(System.currentTimeMillis());
            dataBuilder.addAllServerId(activityInfo.getServerIdList());
            respMsgList.add(dataBuilder.build());
        }

        return respMsgList;

    }

    /**
     * 测试加入历史冠军
     */
    public static void testAddHistoryUser(){
        Random random = new Random();
        int activityId = JiuZhouMgr.getConfig().getActivityId();

        List<UserInfo> userInfoList = UserMgr.getUserInfoList();
        Collections.shuffle(userInfoList);

        Map<Integer,JiuZhouChampionUserData> userDataMap = new ConcurrentHashMap<>();

        for (int i=1;i<4;i++){
            UserInfo userInfo = userInfoList.get(i);
            JiuZhouChampionUserData championUserData = new JiuZhouChampionUserData(userInfo.getUserId(), UserMgr.parseUserBaseInfo(userInfo,userInfo.getOriginalServerId()),106690+i);
            userDataMap.put(i,championUserData);
        }

        JiuZhouActivityChampionData championData = new JiuZhouActivityChampionData(activityId,userDataMap,new ArrayList<>(),System.currentTimeMillis());
        historyChampionMap.put(activityId,championData);

    }

    /**
     * 获取活动的轮次配置
     */
    public static JiuZhouRoundConfig getRoundConfig(int activityId,int round){
        if (config == null){
            return null;
        }
        if (config.getActivityId() != activityId){
            return null;
        }
        Map<Integer, JiuZhouRoundConfig> roundConfigMap = config.getRoundConfigMap();
        if (roundConfigMap == null || roundConfigMap.isEmpty()){
            return null;
        }
        return roundConfigMap.get(round);
    }

    /**
     * 获取随机膜拜奖励
     */
    public static Property getRandomWorshipReward(int activityId){
        if (config == null){
            return null;
        }
        if (config.getActivityId() != activityId){
            return null;
        }
        Random random = new Random();
        int num = random.nextInt(config.getWorshipRewardMinNum()) + config.getWorshipRewardMaxNum() - config.getWorshipRewardMinNum();
        Property property = new Property(config.getWorshipRewardId(),num);
        return property;

    }

    public static void offLine(GamePlayer player) {
        if (config == null) {
            return;
        }
        ActivityInfo activityInfo = config.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }
        // 上个跨服
        CrossJiuZhouProto.CrossJiuZhouLeaveRoomReqMsg.Builder builder = CrossJiuZhouProto.CrossJiuZhouLeaveRoomReqMsg.newBuilder();
        builder.setActivityId(config.getActivityId());
        // 随便给个房间号
        builder.setRoomId(0);
        player.sendPacket(Protocol.C_CROSS_JIU_ZHOU_LEAVE_ROOM, builder);
    }





}
